home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 008a / perl40_2.zip / ARRAY.C < prev    next >
C/C++ Source or Header  |  1991-11-28  |  6KB  |  303 lines

  1. /* $RCSfile: array.c,v $$Revision: 4.0.1.2 $$Date: 91/11/05 16:00:14 $
  2.  *
  3.  *    Copyright (c) 1991, Larry Wall
  4.  *
  5.  *    You may distribute under the terms of either the GNU General Public
  6.  *    License or the Artistic License, as specified in the README file.
  7.  *
  8.  * $Log:    array.c,v $
  9.  * Revision 4.0.1.2  91/11/05  16:00:14  lwall
  10.  * patch11: random cleanup
  11.  * patch11: passing non-existend array elements to subrouting caused core dump
  12.  *
  13.  * Revision 4.0.1.1  91/06/07  10:19:08  lwall
  14.  * patch4: new copyright notice
  15.  *
  16.  * Revision 4.0  91/03/20  01:03:32  lwall
  17.  * 4.0 baseline.
  18.  *
  19.  */
  20.  
  21.  
  22. #include "EXTERN.h"
  23. #include "perl.h"
  24.  
  25.  
  26. STR *
  27. afetch(ar,key,lval)
  28. register ARRAY *ar;
  29. int key;
  30. int lval;
  31. {
  32.     STR *str;
  33.  
  34.  
  35.     if (key < 0 || key > ar->ary_fill) {
  36.     if (lval && key >= 0) {
  37.         if (ar->ary_flags & ARF_REAL)
  38.         str = Str_new(5,0);
  39.         else
  40.         str = str_mortal(&str_undef);
  41.         (void)astore(ar,key,str);
  42.         return str;
  43.     }
  44.     else
  45.         return &str_undef;
  46.     }
  47.     if (!ar->ary_array[key]) {
  48.     if (lval) {
  49.         str = Str_new(6,0);
  50.         (void)astore(ar,key,str);
  51.         return str;
  52.     }
  53.     return &str_undef;
  54.     }
  55.     return ar->ary_array[key];
  56. }
  57.  
  58.  
  59. bool
  60. astore(ar,key,val)
  61. register ARRAY *ar;
  62. int key;
  63. STR *val;
  64. {
  65.     int retval;
  66.  
  67.  
  68.     if (key < 0)
  69.     return FALSE;
  70.     if (key > ar->ary_max) {
  71.     int newmax;
  72.  
  73.  
  74.     if (ar->ary_alloc != ar->ary_array) {
  75.         retval = ar->ary_array - ar->ary_alloc;
  76.         Copy(ar->ary_array, ar->ary_alloc, ar->ary_max+1, STR*);
  77.         Zero(ar->ary_alloc+ar->ary_max+1, retval, STR*);
  78.         ar->ary_max += retval;
  79.         ar->ary_array -= retval;
  80.         if (key > ar->ary_max - 10) {
  81.         newmax = key + ar->ary_max;
  82.         goto resize;
  83.         }
  84.     }
  85.     else {
  86.         if (ar->ary_alloc) {
  87.         newmax = key + ar->ary_max / 5;
  88.           resize:
  89.         Renew(ar->ary_alloc,newmax+1, STR*);
  90.         Zero(&ar->ary_alloc[ar->ary_max+1], newmax - ar->ary_max, STR*);
  91.         }
  92.         else {
  93.         newmax = key < 4 ? 4 : key;
  94.         Newz(2,ar->ary_alloc, newmax+1, STR*);
  95.         }
  96.         ar->ary_array = ar->ary_alloc;
  97.         ar->ary_max = newmax;
  98.     }
  99.     }
  100.     if (ar->ary_flags & ARF_REAL) {
  101.     if (ar->ary_fill < key) {
  102.         while (++ar->ary_fill < key) {
  103.         if (ar->ary_array[ar->ary_fill] != Nullstr) {
  104.             str_free(ar->ary_array[ar->ary_fill]);
  105.             ar->ary_array[ar->ary_fill] = Nullstr;
  106.         }
  107.         }
  108.     }
  109.     retval = (ar->ary_array[key] != Nullstr);
  110.     if (retval)
  111.         str_free(ar->ary_array[key]);
  112.     }
  113.     else
  114.     retval = 0;
  115.     ar->ary_array[key] = val;
  116.     return retval;
  117. }
  118.  
  119.  
  120. ARRAY *
  121. anew(stab)
  122. STAB *stab;
  123. {
  124.     register ARRAY *ar;
  125.  
  126.  
  127.     New(1,ar,1,ARRAY);
  128.     ar->ary_magic = Str_new(7,0);
  129.     ar->ary_alloc = ar->ary_array = 0;
  130.     str_magic(ar->ary_magic, stab, '#', Nullch, 0);
  131.     ar->ary_max = ar->ary_fill = -1;
  132.     ar->ary_flags = ARF_REAL;
  133.     return ar;
  134. }
  135.  
  136.  
  137. ARRAY *
  138. afake(stab,size,strp)
  139. STAB *stab;
  140. register int size;
  141. register STR **strp;
  142. {
  143.     register ARRAY *ar;
  144.  
  145.  
  146.     New(3,ar,1,ARRAY);
  147.     New(4,ar->ary_alloc,size+1,STR*);
  148.     Copy(strp,ar->ary_alloc,size,STR*);
  149.     ar->ary_array = ar->ary_alloc;
  150.     ar->ary_magic = Str_new(8,0);
  151.     str_magic(ar->ary_magic, stab, '#', Nullch, 0);
  152.     ar->ary_fill = size - 1;
  153.     ar->ary_max = size - 1;
  154.     ar->ary_flags = 0;
  155.     while (size--) {
  156.     if (*strp)
  157.         (*strp)->str_pok &= ~SP_TEMP;
  158.     strp++;
  159.     }
  160.     return ar;
  161. }
  162.  
  163.  
  164. void
  165. aclear(ar)
  166. register ARRAY *ar;
  167. {
  168.     register int key;
  169.  
  170.  
  171.     if (!ar || !(ar->ary_flags & ARF_REAL) || ar->ary_max < 0)
  172.     return;
  173.     /*SUPPRESS 560*/
  174.     if (key = ar->ary_array - ar->ary_alloc) {
  175.     ar->ary_max += key;
  176.     ar->ary_array -= key;
  177.     }
  178.     for (key = 0; key <= ar->ary_max; key++)
  179.     str_free(ar->ary_array[key]);
  180.     ar->ary_fill = -1;
  181.     Zero(ar->ary_array, ar->ary_max+1, STR*);
  182. }
  183.  
  184.  
  185. void
  186. afree(ar)
  187. register ARRAY *ar;
  188. {
  189.     register int key;
  190.  
  191.  
  192.     if (!ar)
  193.     return;
  194.     /*SUPPRESS 560*/
  195.     if (key = ar->ary_array - ar->ary_alloc) {
  196.     ar->ary_max += key;
  197.     ar->ary_array -= key;
  198.     }
  199.     if (ar->ary_flags & ARF_REAL) {
  200.     for (key = 0; key <= ar->ary_max; key++)
  201.         str_free(ar->ary_array[key]);
  202.     }
  203.     str_free(ar->ary_magic);
  204.     Safefree(ar->ary_alloc);
  205.     Safefree(ar);
  206. }
  207.  
  208.  
  209. bool
  210. apush(ar,val)
  211. register ARRAY *ar;
  212. STR *val;
  213. {
  214.     return astore(ar,++(ar->ary_fill),val);
  215. }
  216.  
  217.  
  218. STR *
  219. apop(ar)
  220. register ARRAY *ar;
  221. {
  222.     STR *retval;
  223.  
  224.  
  225.     if (ar->ary_fill < 0)
  226.     return Nullstr;
  227.     retval = ar->ary_array[ar->ary_fill];
  228.     ar->ary_array[ar->ary_fill--] = Nullstr;
  229.     return retval;
  230. }
  231.  
  232.  
  233. aunshift(ar,num)
  234. register ARRAY *ar;
  235. register int num;
  236. {
  237.     register int i;
  238.     register STR **sstr,**dstr;
  239.  
  240.  
  241.     if (num <= 0)
  242.     return;
  243.     if (ar->ary_array - ar->ary_alloc >= num) {
  244.     ar->ary_max += num;
  245.     ar->ary_fill += num;
  246.     while (num--)
  247.         *--ar->ary_array = Nullstr;
  248.     }
  249.     else {
  250.     (void)astore(ar,ar->ary_fill+num,(STR*)0);    /* maybe extend array */
  251.     dstr = ar->ary_array + ar->ary_fill;
  252.     sstr = dstr - num;
  253. #ifdef BUGGY_MSC5
  254.  # pragma loop_opt(off)    /* don't loop-optimize the following code */
  255. #endif /* BUGGY_MSC5 */
  256.     for (i = ar->ary_fill - num; i >= 0; i--) {
  257.         *dstr-- = *sstr--;
  258. #ifdef BUGGY_MSC5
  259.  # pragma loop_opt()    /* loop-optimization back to command-line setting */
  260. #endif /* BUGGY_MSC5 */
  261.     }
  262.     Zero(ar->ary_array, num, STR*);
  263.     }
  264. }
  265.  
  266.  
  267. STR *
  268. ashift(ar)
  269. register ARRAY *ar;
  270. {
  271.     STR *retval;
  272.  
  273.  
  274.     if (ar->ary_fill < 0)
  275.     return Nullstr;
  276.     retval = *ar->ary_array;
  277.     *(ar->ary_array++) = Nullstr;
  278.     ar->ary_max--;
  279.     ar->ary_fill--;
  280.     return retval;
  281. }
  282.  
  283.  
  284. int
  285. alen(ar)
  286. register ARRAY *ar;
  287. {
  288.     return ar->ary_fill;
  289. }
  290.  
  291.  
  292. afill(ar, fill)
  293. register ARRAY *ar;
  294. int fill;
  295. {
  296.     if (fill < 0)
  297.     fill = -1;
  298.     if (fill <= ar->ary_max)
  299.     ar->ary_fill = fill;
  300.     else
  301.     (void)astore(ar,fill,Nullstr);
  302. }
  303.